www.gusucode.com > VC++ 基于IE内核功能很齐全的浏览器(支持多标签)-源码程序 > VC++ 基于IE内核功能很齐全的浏览器(支持多标签)-源码程序/code/Explorer/BBSystemTray.cpp

    //Download by http://www.NewXing.com
// BBSystemTray.cpp: implementation of the CBBSystemTray class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "BBSystemTray.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


IMPLEMENT_DYNAMIC(CBBSystemTray, CWnd)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBBSystemTray::CBBSystemTray()
{
	Init();
}


BOOL CBBSystemTray::Create(CWnd* pParent, UINT uCallbackMessage, LPCTSTR szToolTipText, HICON hIcon, UINT uMenuID)
{
        
    // 自定义消息是否大于WM_USER
    ASSERT(uCallbackMessage >= WM_USER);

    //检查提示字符是否大于64个字符,因为提示信息不允许大于64字符
    ASSERT(_tcslen(szToolTipText) <= 64);    
	CWnd::CreateEx(0, AfxRegisterWndClass(0),
			_T(""), WS_POPUP, 0,0,10,10, NULL, 0);    
    m_tnd.cbSize = sizeof(NOTIFYICONDATA);
    m_tnd.hWnd   = pParent->GetSafeHwnd()? pParent->GetSafeHwnd() : m_hWnd;
    m_tnd.uID    = uMenuID;
    m_tnd.hIcon  = hIcon;
    m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
    m_tnd.uCallbackMessage = uCallbackMessage;
    _tcscpy(m_tnd.szTip, szToolTipText);

    //设置图标
	
    VERIFY(m_bAdded =Shell_NotifyIcon(NIM_ADD, &m_tnd));	
    return m_bAdded;
}

BOOL CBBSystemTray::Create(LPCTSTR szToolTipText, HICON hIcon, UINT uMenuID)
{
	return Create(NULL,WM_DEFAULT_NOTIFY_MESSAGE,szToolTipText,hIcon,uMenuID);
}

//初始化
BOOL CBBSystemTray::Init()
{
	m_bAdded=FALSE;
    memset(&m_tnd, 0, sizeof(m_tnd));
    m_nDefaultMenuItemID = 0;
    m_bDefaultMenuItemByPos = TRUE;
	return TRUE;
}

CBBSystemTray::~CBBSystemTray()
{
	//删除图标
    RemoveIcon();    
}


void CBBSystemTray::RemoveIcon()
{
	ASSERT(m_bAdded);
	if (!m_bAdded) 
		return;
    m_tnd.uFlags = 0;
    Shell_NotifyIcon(NIM_DELETE, &m_tnd);    
}

//改变图标
BOOL CBBSystemTray::SetIcon(HICON hIcon)
{
	ASSERT(m_bAdded);
	if (!m_bAdded) 
		return FALSE;
	
	m_tnd.uFlags = NIF_ICON;
	m_tnd.hIcon = hIcon;
	return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
	
}

BOOL CBBSystemTray::SetIcon(UINT nIDResource)
{
    HICON hIcon = AfxGetApp()->LoadIcon(nIDResource);
    return SetIcon(hIcon);
}
 
HICON CBBSystemTray::GetIcon() const
{	
    return m_bAdded?m_tnd.hIcon:NULL;
}

//修改提示
BOOL CBBSystemTray::SetTooltipText(LPCTSTR pszTip)
{
    m_tnd.uFlags = NIF_TIP;
    _tcscpy(m_tnd.szTip, pszTip);
    return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
}

//得到当前提示
CString CBBSystemTray::GetTooltipText() const
{
	ASSERT(m_bAdded);
	if(m_bAdded)
	{
		CString strText;
		strText = m_tnd.szTip;
		return strText;
	}
	else
	{
		return "";
	}
}


//设置消息的处理Notify窗口
BOOL CBBSystemTray::SetNotificationWnd(CWnd* pWnd)
{
	ASSERT(m_bAdded);
	if(!m_bAdded)
		return FALSE;
    ASSERT(pWnd && ::IsWindow(pWnd->GetSafeHwnd()));
    m_tnd.hWnd = pWnd->GetSafeHwnd();
    m_tnd.uFlags = 0;
    return Shell_NotifyIcon(NIM_MODIFY, &m_tnd);
}

CWnd* CBBSystemTray::GetNotificationWnd() const
{
    return CWnd::FromHandle(m_tnd.hWnd);
}

//设置默认的菜单项(双击图标打开),bByPos为TRUE表示从位置上的序号,否则以菜单ID为第一参数
BOOL CBBSystemTray::SetMenuDefaultItem(UINT uItem, BOOL bByPos)
{
    if ((m_nDefaultMenuItemID == uItem) && (m_bDefaultMenuItemByPos == bByPos)) 
        return TRUE;

    m_nDefaultMenuItemID = uItem;
    m_bDefaultMenuItemByPos = bByPos;   

    CMenu menu, *pSubMenu;

    if (!menu.LoadMenu(m_tnd.uID)) return FALSE;
    if (!(pSubMenu = menu.GetSubMenu(0))) return FALSE;

    ::SetMenuDefaultItem(pSubMenu->m_hMenu, m_nDefaultMenuItemID, m_bDefaultMenuItemByPos);

    return TRUE;
}

void CBBSystemTray::GetMenuDefaultItem(UINT& uItem, BOOL& bByPos)
{
    uItem = m_nDefaultMenuItemID;
    bByPos = m_bDefaultMenuItemByPos;
}

/////////////////////////////////////////////////////////////////////////////
// CBBSystemTray message handlers

BEGIN_MESSAGE_MAP(CBBSystemTray, CWnd)
	//{{AFX_MSG_MAP(CBBSystemTray)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


//该函数是默认的消息处理函数,如有需要改变默认的操作,可以重载该函数
LRESULT CBBSystemTray::OnTrayNotification(WPARAM wParam, LPARAM lParam) 
{
    //检查ID是否一样,是否本实例
    if (wParam != m_tnd.uID)
        return 0L;

    CMenu menu, *pSubMenu;
    CWnd* pTarget = AfxGetMainWnd();

    //处理右键,显示菜单
    if (LOWORD(lParam) == WM_RBUTTONUP)
    {    
        if (!menu.LoadMenu(m_tnd.uID)) return 0;
        if (!(pSubMenu = menu.GetSubMenu(0))) return 0;

        //设置默认的菜单项(加粗)
        ::SetMenuDefaultItem(pSubMenu->m_hMenu, m_nDefaultMenuItemID, m_bDefaultMenuItemByPos);

        //显示菜单
        CPoint pos;
        GetCursorPos(&pos);

		//窗口置前,使其活动
        pTarget->SetForegroundWindow();  
		::TrackPopupMenu(pSubMenu->m_hMenu, 0, pos.x, pos.y, 0, 
                         pTarget->GetSafeHwnd(), NULL);

        //不知怎么样,需要调用下面的函数,就没有问题
        pTarget->PostMessage(WM_NULL, 0, 0);
        menu.DestroyMenu();
    } 
    else if (LOWORD(lParam) == WM_LBUTTONDBLCLK) 
    {
        //处理双击--执行默认的菜单操作
        pTarget->SetForegroundWindow();  
        UINT uItem;
		//获得默认菜单
        if (m_bDefaultMenuItemByPos)
        {
            if (!menu.LoadMenu(m_tnd.uID)) return 0;
            if (!(pSubMenu = menu.GetSubMenu(0))) return 0;
            uItem = pSubMenu->GetMenuItemID(m_nDefaultMenuItemID);
        }
        else
            uItem = m_nDefaultMenuItemID;        
		//处理菜单的消息
        pTarget->SendMessage(WM_COMMAND, uItem, 0);
        menu.DestroyMenu();
    }
    return 1;
}

LRESULT CBBSystemTray::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	//处理消息Notify操作
    if (message == m_tnd.uCallbackMessage)
        return OnTrayNotification(wParam, lParam);
	
	return CWnd::WindowProc(message, wParam, lParam);
}